package sy4_Creational_Pattern.builder;

/**
 * 考虑去快餐店，有多种套餐选择
 * 假定套餐有食品和饮料两部分组成
 * 使用Director的construct()，完成产品的建造（可以使用钩子方法控制产品的建造）
 */
class Product {
    //产品部件的名称
    private String food;
    private String drink;

    public String getFood() {
        return food;
    }

    public void setFood(String food) {
        this.food = food;
    }

    public String getDrink() {
        return drink;
    }

    public void setDrink(String drink) {
        this.drink = drink;
    }

    @Override
    public String toString() {
        return "Product{" +
                "food='" + food + '\'' +
                ", drink='" + drink + '\'' +
                '}';
    }
}

abstract class Builder {    //抽象建造者
    private String name;  //名称
    protected Product product = new Product();  //产品

    public abstract void buildFood();  //抽象方法

    public abstract void buildDrink();   //抽象方法

    public Product buildProduct() {  //普通方法
        return product;
    }

    public Builder(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

class ConcreteBuilderA extends Builder {
    public ConcreteBuilderA() {
        super("肯德基快餐");
    }

    @Override
    public void buildFood() {
        product.setFood("炸鸡");
    }

    @Override
    public void buildDrink() {
        product.setDrink("可乐");
    }
}

class ConcreteBuilderB extends Builder {

    public ConcreteBuilderB() {
        super("麦当劳快餐");
    }

    @Override
    public void buildFood() {
        product.setFood("汉堡");
    }

    @Override
    public void buildDrink() {
        product.setDrink("柠檬茶");
    }
}

class Director {

    private Builder builder;  //聚合

    public Director(Builder builder) { //构造器注入
        this.builder = builder;
    }

    public Product construct() {   //控制产品的建造过程
        //可以使用钩子方法控制建造细节
        builder.buildFood();
        builder.buildDrink();
        return builder.buildProduct();
    }
}

public class Client {
    public static void main(String[] args) {
        //创建建造者
        Builder builder = new ConcreteBuilderA();
        //Builder builder = new ConcreteBuilderB();
        //创建指挥者
        Director director = new Director(builder);
        //建造获得产品，控制产品的建造过程
        Product product = director.construct();
        //使用产品对象
        System.out.println(builder.getName() + "：" + product.getFood() + "+" + product.getDrink());

        //不使用指挥者，将不能建造完整的产品
        /*Builder builder = new ConcreteBuilderA();
        Product product = builder.buildProduct();
        System.out.println(builder.getName() + "：" + product.getFood() + "+" + product.getDrink());*/
    }
}
